﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Emgu.CV.UI;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;
using Emgu.CV.VideoSurveillance;
using System.Threading;
using System.Xml;
using System.Xml.XPath;
using System.Text.RegularExpressions;

namespace MAVI.BillRecognition.BillDetection.source
{
    public class BillDetection 
    {
       public string XMLPath ="C:\\ptProiect\\bancnote.xml";

        public String Detect(Bitmap bmp)
        {
            
            // threashold for the number of detected features 
            int maxFeatures = 40;
            
            // variable that holds the name of the bill of the phrase "not found" 
            // if the thershold is not passed by any detected bill 
            String numeleBancnotei = "not found";
            
            // method Run from SURFBillDetection class returns a string containing the 
            // number of features for each bill front or back + the name of that bill
            // separated by the character "|"
            //String nrFeaturesSiNumeleBancnotei = "";
            
            // we will split the nrFeaturesSiNumeleBancnotei string relative to the "|"
            // character and on the first position splitNumarFeatures will have 
            // the number of detected features and aon the second position the bill's name
            string[] splitNumberFeatures = new string[2];

            // make a new instance of the class SURFBillDetection
            

            // the image we will work on will be given as a parameter for the 
            // Detect method
            

            // make a new list of type Bill bancnote
            List<Bill> bancnote = parseXML();
            SURFBillDetection.DaList.Clear();
            // initialize the number of features with 0
            int numberFeatures = 0;
            
            // take each bill fron the bill list "bancnote"
            List<Thread> listaDeThread = new List<Thread>();
            foreach (Bill banc in bancnote)
            {

                SURFBillDetection detectare = new SURFBillDetection();
                detectare.ImagineLuata = bmp;
                detectare.TestImageFront = banc.TestImageFront;
                detectare.TestImageBack = banc.TestImageBack;
                detectare.NumeleBancnotei = banc.Name;
                Thread t = new Thread(new ThreadStart(detectare.Run));
                listaDeThread.Add(t);
                t.Start();
                Thread.Sleep(10);

                // returned string fron the Run method 
               // nrFeaturesSiNumeleBancnotei = detectare.Run(banc);

                // splits the above returned string by the character "|"
                //splitNumberFeatures = nrFeaturesSiNumeleBancnotei.Split('|');

                // parse the first element of splitNumberFeartures into integer 
                // beacuse it is a string 
                //numberFeatures = Int32.Parse(splitNumberFeatures[0]);
                
                // verify if the number of features for each bill is larger than the 
                // threshold
              /* if (numberFeatures > maxFeatures)
               {
                   // if it is , then give the threshold the new value number of features 
                   // so that the name of the bill that returned the maximum number of features 
                   // is kept in numeleBancnotei at the end of the foreach
                   maxFeatures = numberFeatures;
                   numeleBancnotei = splitNumberFeatures[1];
               }
               */ 
            }

            foreach (Thread trh in listaDeThread)
            {
                trh.Join();
            }

            foreach (String nrAndName in SURFBillDetection.DaList)
            {
                splitNumberFeatures = nrAndName.Split('|');
                numberFeatures = Int32.Parse(splitNumberFeatures[0]);
                if (numberFeatures > maxFeatures)
                {
                    maxFeatures = numberFeatures;
                    numeleBancnotei = splitNumberFeatures[1];
                }
            }
 
            return numeleBancnotei;
            
        }
        
        
        public List<Bill> parseXML()
        {
            // makes a new list of type Bill that will be filled with object 
            // that are taken from the XML created for the bills
            List<Bill> bancnote = new List<Bill>();
            XmlDocument doc = new XmlDocument();
            doc.Load(XMLPath);
            XPathNavigator navigator = doc.CreateNavigator();
            navigator.MoveToRoot();

            // start with the parent node of the entire XML 
            if (navigator.MoveToFirstChild())
            {
                if (navigator.MoveToFirstChild())
                {
                    do
                    {
                        // variables that will have assigned to them the walues 
                        // inside each child node of the XML 
                        String billName = String.Empty;
                        String soundPath = String.Empty;
                        String testImageFront = String.Empty;
                        String testImageBack = String.Empty;
                        String countryName = String.Empty;
                        String countryCode = String.Empty;

                        // if the node's name is Name then in the string variable 
                        // billName the value inside the atribute is given to it ;
                        // it is the same for all the other child-nodes
                        if (navigator.MoveToChild("Name", String.Empty))
                        {
                            billName = navigator.Value;
                            navigator.MoveToParent();
                        }

                        if (navigator.MoveToChild("SoundPath", String.Empty))
                        {
                            soundPath = navigator.Value;
                            navigator.MoveToParent();
                        }
                        if (navigator.MoveToChild("TestImageFront", String.Empty))
                        {
                            testImageFront = navigator.Value;
                            navigator.MoveToParent();
                        }
                        if (navigator.MoveToChild("TestImageBack", String.Empty))
                        {
                            testImageBack = navigator.Value;
                            navigator.MoveToParent();
                        }
                        if (navigator.MoveToChild("Country", String.Empty))
                        {
                            if (navigator.MoveToChild("Name", String.Empty))
                            {
                                countryName = navigator.Value;
                                navigator.MoveToParent();
                            }
                            if (navigator.MoveToChild("Code", String.Empty))
                            {
                                countryCode = navigator.Value;
                                navigator.MoveToParent();
                            }
                            navigator.MoveToParent();

                        }

                        // verifies that the values are not empty for all the variables assigned 
                        if (!billName.Equals(String.Empty) && !soundPath.Equals(String.Empty) && !testImageFront.Equals(String.Empty) && !testImageBack.Equals(String.Empty) && !countryName.Equals(String.Empty) && !countryCode.Equals(String.Empty))
                        {
                            // if all the variable values are not empty then a new object of type bill is made 
                            // using the constructor found in the class Bill
                            Bill bill = new Bill(billName, soundPath,testImageFront,testImageBack,countryName,countryCode);

                            //add the new instance to the list created at the begining of the function
                            bancnote.Add(bill);
                           
                        }
                    }

                    while (navigator.MoveToNext());
                }
            }

            // returns the list created by the function containing the bills fron the XML file
            return bancnote;

        }
        

    }
}
